package org.com.yz.dubbo.web.impl;

import com.alibaba.fastjson.JSONObject;
import org.com.yz.common.config.ConfigureTest;
import org.com.yz.common.config.IPostService;
import org.com.yz.common.config.ServiceName;
import org.com.yz.common.util.CacheUtil;
import org.com.yz.common.util.MyLog;
import org.com.yz.common.util.Signature;
import org.com.yz.common.util.XmlFormatter;
import org.com.yz.dal.dao.mapper.AuthenticationDetailMapper;
import org.com.yz.dal.dao.mapper.BankCardMapper;
import org.com.yz.dal.dao.model.AuthenticationDetail;
import org.com.yz.dal.dao.model.BankCard;
import org.com.yz.dal.dao.model.MchConfig;
import org.com.yz.dubbo.web.core.AsyncNotify;
import org.com.yz.dubbo.web.service.ScheuldBankCardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;


/**
 * 定时更新 待绑定银行卡 实现类
 */
@Service
public class ScheuldBankCardServiceImpl implements ScheuldBankCardService {

    private static final MyLog log = MyLog.getLog(ScheuldBankCardServiceImpl.class);

    @Autowired
    private BankCardMapper bankCardMapper;

    @Autowired
    private AuthenticationDetailMapper authenticationDetailMapper;

    @Autowired
    private AsyncNotify asyncNotify;


    /**
     * 更新银行卡信息、鉴权信息，并异步发通知
     *
     * @param bankCardfr
     * @throws InterruptedException
     */
    @Override
    public void updateBankCard(BankCard bankCardfr) throws InterruptedException {
        Map params = updateBankCardInfo(bankCardfr);
        if ("1".equals(params.get("status")) || "2".equals(params.get("status"))) {
            asyncNotify.bankNotify(bankCardfr, params);//对私绑卡异步通知(成功或失败通知，认证处理中或待认证不通知)
        }
    }


    /**
     * 查询银行卡鉴权信息，更新银行卡信息表、鉴权信息表
     *
     * @param bankCardfr
     * @return
     */
    @Transactional
    public Map updateBankCardInfo(BankCard bankCardfr) {
        MchConfig config = CacheUtil.me().getMchConfigInfo(bankCardfr.getMchNo(), "0");
        //MchConfig config = new MchConfig();
        String taro = bankCardfr.getTracNo();
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("timestamp", org.com.yz.common.util.DateUtil.getSeqString());
        paramMap.put("appid", config.getApp_id());
        paramMap.put("service", ServiceName.getSingleauthQuery());
        paramMap.put("ver", ServiceName.getVer());
        paramMap.put("sign_type", ServiceName.getSign_typeRsa());
        paramMap.put("trac_no", taro);   //系统跟踪号
        paramMap.put("mac", Signature.generateMAC(paramMap, bankCardfr.getMchNo()));
        String result = IPostService.txn(ConfigureTest.isDevEnv() ? ConfigureTest.EP_DEV_API : ConfigureTest.EP_PROD_API, paramMap, bankCardfr.getMchNo());  //发送请求
        log.info("定时查询对私鉴权返回的数据为：" + XmlFormatter.formatJson(result));
        JSONObject jsonObject = (JSONObject) JSONObject.parse(result);  //转换为json
        BankCard bankCard = new BankCard();
        HashMap<String, String> params = new HashMap<String, String>();
        AuthenticationDetail authenticationDetail = new AuthenticationDetail();//鉴权明细信息
        if (result.contains("errcode")) {  //代表失败( 生产环境不存在此逻辑,进入此逻辑的数据为 第一次鉴权请求成功，后续查鉴权结果的数据)
            bankCard.setTracNo(taro);
            bankCardMapper.deleteTracNo(bankCard);
            params.put("status", "2");
            params.put("message", jsonObject.getString("errmsg"));
            log.info(cn.hutool.core.date.DateUtil.now() + "定时绑卡失败，订单号" + taro);
            authenticationDetail.setMchNo(bankCardfr.getMchNo());//商户号
            authenticationDetail.setOrderNo(taro);//订单号/请求追踪号
            authenticationDetail.setMchAccntNo(bankCardfr.getMchAccntNo());
            authenticationDetailMapper.updateAuthenticationDetail(authenticationDetail);//更新鉴权明细信息
            log.info(cn.hutool.core.date.DateUtil.now() + "定时绑卡失败，失败原因:" + jsonObject.get("errmsg").toString());
        }
        if (result.contains("appid") && result.contains("auth_status")) {  //代表成功
            if ("1".equals(jsonObject.get("auth_status"))) {   //认证成功
                bankCard.setStatus("success");
                bankCard.setRemark("交易成功");
                bankCard.setTracNo(taro);
                bankCardMapper.undateNoSuess(bankCard);//更新银行卡信息表
                //更新鉴权明细信息
                authenticationDetail.setStatus("success");//状态
                authenticationDetail.setRemark("绑定成功");
                params.put("status", "1");
                params.put("message", "绑定成功");
                log.info(cn.hutool.core.date.DateUtil.now() + "定时绑卡成功，订单号" + taro);
                authenticationDetail.setMchNo(bankCardfr.getMchNo());//商户号
                authenticationDetail.setOrderNo(taro);//订单号/请求追踪号
                authenticationDetail.setMchAccntNo(bankCardfr.getMchAccntNo());
                authenticationDetailMapper.updateAuthenticationDetail(authenticationDetail);//更新鉴权明细信息
            } else if ("2".equals(jsonObject.get("auth_status"))) {   //认证失败
                bankCard.setTracNo(taro);
                bankCardMapper.deleteTracNo(bankCard);
                //更新鉴权明细信息表
                authenticationDetail.setStatus("fail");
                authenticationDetail.setRemark(jsonObject.getString("remark"));
                params.put("status", "2");
                params.put("message", jsonObject.getString("remark"));

                log.info(cn.hutool.core.date.DateUtil.now() + "定时绑卡失败，订单号" + taro);
                authenticationDetail.setMchNo(bankCardfr.getMchNo());//商户号
                authenticationDetail.setOrderNo(taro);//订单号/请求追踪号
                authenticationDetail.setMchAccntNo(bankCardfr.getMchAccntNo());
                authenticationDetailMapper.updateAuthenticationDetail(authenticationDetail);//更新鉴权明细信息
            } else if ("0".equals(jsonObject.get("auth_status"))) {//待认证
                params.put("status", "0");
//                params.put("message", jsonObject.getString("remark"));
            } else if ("3".equals(jsonObject.get("auth_status"))) {//认证处理中
                params.put("status", "0");
//                params.put("message", jsonObject.getString("remark"));
            }
        }
        return params;

    }

}
